package stdio.costa.imoca.spi;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.qiniu.qbox.auth.DigestAuthClient;
import com.qiniu.qbox.rs.PutAuthRet;
import com.qiniu.qbox.rs.PutFileRet;
import com.qiniu.qbox.rs.RSClient;
import com.qiniu.qbox.rs.RSService;

@Service
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class QiniuStorageAdapter implements StorageSpi {

	private static final Logger logger = LoggerFactory.getLogger(QiniuStorageAdapter.class);
	
	@Value("#{storage['qiniu.bucket.name']}")
	private String bucketName;
	
	@Value("#{storage['qiniu.publish.domain']}")
	private String publishDomain;
	
	@Override
	@Async
	public void uploadAsynchronously(InputStream file, String mimeType, String uuid) throws Exception {
		uploadSynchronously(file, mimeType, uuid);
	}

	@Override
	public String buildGetUrl(String uuid, int width, int height) {
		return new StringBuilder(publishDomain).append(uuid).append("?imageView/1/w/").append(width).append("/h/").append(height).toString();
	}
	
	protected Map<String, String> buildCallbackParams(String uuid) {
		HashMap<String, String> callbackParams = new HashMap<String, String>();
		callbackParams.put("key", uuid);
		return callbackParams;
	}

	@Override
	public void uploadSynchronously(InputStream file, String mimeType, String uuid) throws Exception {
		RSService service = new RSService(new DigestAuthClient(), bucketName);
		PutAuthRet putAuthRet = service.putAuth();
		if (putAuthRet.ok()) {
			Map<String, String> callbackParams = buildCallbackParams(uuid);
			PutFileRet putFileRet = RSClient.putFile(putAuthRet.getUrl(), bucketName, uuid, mimeType, file, null, callbackParams);
			if(putFileRet.ok()) {
				logger.info("{} has been uploaded to qiniu's cloud storage.", uuid);
			} else {
				logger.error("Error occurs while uploading file {}", uuid, putFileRet.exception.getMessage());
				throw putFileRet.exception;
			}
		}
	}
}
